home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
076-100
/
disk_077
/
quest
/
qmain.d
< prev
next >
Wrap
Text File
|
1992-05-06
|
13KB
|
617 lines
#include:util.g
#q.g
/* a data structure we need to keep track of where we've dropped things: */
type
ContentsList_t = struct {
*ContentsList_t cl_next;
long cl_line, cl_column;
*List_t cl_contents;
};
/* codes for the types of words in a sentence: */
Id_t
VERB = 1,
ARTICLE = 2,
ADJECTIVE = 3,
NOUN = 4,
PREPOSITION = 5,
PUNCTUATION = 6,
AUXILLIARY = 7,
/* id's for some words that we need to know: */
/* verbs: */
NORTH = 1001,
SOUTH = 1002,
EAST = 1003,
WEST = 1004,
QUIT = 1005,
DROP = 1006,
PUT = 1007,
GET = 1008,
PICK = 1009,
LOOK = 1010,
LONG = 1011,
DUMP = 1012,
/* articles: */
THE = 2001,
/* adjectives: */
/* nouns: */
SWORD = 4001,
BOTTLE = 4002,
KNIFE = 4003,
PURSE = 4004,
AMULET = 4005,
/* prepositions: */
/* punctuation: */
PERIOD = 6001,
/* auxilliaries: */
DOWN = 7001,
UP = 7002,
AROUND = 7003,
/* some properties and attributes we need: */
CARRYABLE = 8002; /* object can be carried */
channel output text TextOut;
long PlayerLine, PlayerColumn, MoveCount;
*List_t CarryList, CarryNext;
*ContentsList_t Contents;
*char Condition;
bool Quit;
/*
* scenery - simple scenery generator.
*/
proc scenery(long l, c)C2:
long l1, c1;
l1 := |l % 30;
if l1 >= 15 then l1 := l1 - 30 fi;
c1 := |c % 30;
if c1 >= 15 then c1 := c1 - 30 fi;
if l1 * l1 + c1 * c1 <= 16 or l1 = 0 or c1 = 0 then
C2('~', '~')
elif l1 * l1 + c1 * c1 <= 25 then
C2('\#', '\#')
else
l := l * 997 + c + 10321;
l := l * l;
if l / 32 % 8 = 0 then
C2('/', '\\')
else
C2(' ', ' ')
fi
fi
corp;
/*
* findCList - find the contents list for the given location.
*/
proc findCList(long line, column)*ContentsList_t:
*ContentsList_t cl;
cl := Contents;
while cl ~= nil and (cl*.cl_line ~= line or cl*.cl_column ~= column) do
cl := cl*.cl_next;
od;
cl
corp;
/*
* findContents - return the actual contents of a location.
*/
proc findContents(long line, column)*List_t:
*ContentsList_t cl;
cl := findCList(line, column);
if cl = nil then
nil
else
cl*.cl_contents
fi
corp;
/*
* addContents - add a contents list for the given location, if not there.
*/
proc addContents(long line, column)**List_t:
*ContentsList_t cl;
cl := findCList(line, column);
if cl = nil then
cl := new(ContentsList_t);
cl*.cl_next := Contents;
cl*.cl_line := line;
cl*.cl_column := column;
cl*.cl_contents := nil;
Contents := cl;
fi;
&cl*.cl_contents
corp;
/*
* termContents - clean up all the contents stuff.
*/
proc termContents()void:
*ContentsList_t cl;
while Contents ~= nil do
cl := Contents;
Contents := cl*.cl_next;
lFree(cl*.cl_contents);
free(cl);
od;
corp;
/*
* lookAround - list the objects at this location.
*/
proc lookAround()bool:
*List_t il;
il := findContents(PlayerLine, PlayerColumn);
if il ~= nil then
write(TextOut; "Nearby: ");
while il ~= nil do
write(TextOut; psGet(il*.il_this));
il := il*.il_next;
if il ~= nil then
write(TextOut; ", ");
fi;
od;
true
else
false
fi
corp;
/*
* move - move our character in the given relative direction.
*/
proc move(long lineDelta, columnDelta)void:
char ch;
ch := scAt(PlayerLine + lineDelta, PlayerColumn + columnDelta)[0];
if ch = '\#' or ch = '/' or ch = 'T' then
write(TextOut; "You can't move there.");
Condition := "Dazed";
scUpdate(4);
else
PlayerLine := PlayerLine + lineDelta;
PlayerColumn := PlayerColumn + columnDelta;
scMove(0, PlayerLine, PlayerColumn);
MoveCount := MoveCount + 1;
scUpdate(3);
if Condition* ~= 'H' then
if Condition* = 'D' then
Condition := "Bruised";
else
Condition := "Healthy";
fi;
scUpdate(4);
fi;
if lookAround() then fi;
fi;
corp;
/*
* gramInit - set up our dictionary and grammar.
*/
proc gramInit()void:
psWord(NORTH, "north", VERB);
psWord(SOUTH, "south", VERB);
psWord(EAST, "east", VERB);
psWord(WEST, "west", VERB);
psWord(NORTH, "n", VERB);
psWord(SOUTH, "s", VERB);
psWord(EAST, "e", VERB);
psWord(WEST, "w", VERB);
psWord(QUIT, "quit", VERB);
psWord(DROP, "drop", VERB);
psWord(PUT, "put", VERB);
psWord(GET, "get", VERB);
psWord(PICK, "pick", VERB);
psWord(LOOK, "look", VERB);
psWord(LONG, "long", VERB);
psWord(DUMP, "dump", VERB);
psWord(THE, "the", ARTICLE);
psWord(THE, "a", ARTICLE);
psWord(THE, "an", ARTICLE);
psWord(THE, "one", ARTICLE);
psWord(SWORD, "sword", NOUN);
psWord(BOTTLE, "bottle", NOUN);
psWord(KNIFE, "knife", NOUN);
psWord(PURSE, "purse", NOUN);
psWord(AMULET, "amulet", NOUN);
psWord(PERIOD, ".", PUNCTUATION);
psWord(PERIOD, "!", PUNCTUATION);
psWord(DOWN, "down", AUXILLIARY);
psWord(UP, "up", AUXILLIARY);
psWord(AROUND, "around", AUXILLIARY);
/* rule #1 - look [around] */
psgBegin(1);
psgWord(f_reqId, LOOK);
psgWord(f_optId, AROUND);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #2 - drop [ART] N */
psgBegin(2);
psgWord(f_reqId, DROP);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #3 - put down [ART] N */
psgBegin(3);
psgWord(f_reqId, PUT);
psgWord(f_reqId, DOWN);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #4 - put [ART] N down */
psgBegin(4);
psgWord(f_reqId, PUT);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_reqId, DOWN);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #5 - get [ART] N */
psgBegin(5);
psgWord(f_reqId, GET);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #6 - pick up [ART] N */
psgBegin(6);
psgWord(f_reqId, PICK);
psgWord(f_reqId, UP);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #7 - pick [ART] N up */
psgBegin(7);
psgWord(f_reqId, PICK);
psgWord(f_optType, ARTICLE);
psgWord(f_reqType, NOUN);
psgWord(f_reqId, UP);
psgWord(f_optType, PUNCTUATION);
psgEnd();
/* rule #8 - V */
psgBegin(8);
psgWord(f_reqType, VERB);
psgWord(f_optType, PUNCTUATION);
psgEnd();
corp;
/*
* getObjectC2 - return the C2 for the given object:
*/
proc getObjectC2(Id_t id)C2:
case id
incase SWORD:
C2('s', 'w')
incase BOTTLE:
C2('b', 'o')
incase KNIFE:
C2('k', 'n')
incase PURSE:
C2('p', 'u')
incase AMULET:
C2('a', 'm')
default:
C2('?', '?')
esac
corp;
/*
* carryInit - initialize our list of what we are carrying.
*/
proc carryInit()void:
Contents := nil;
CarryList := nil;
lAppend(&CarryList, SWORD);
lAppend(&CarryList, BOTTLE);
lAppend(&CarryList, KNIFE);
lAppend(&CarryList, PURSE);
lAppend(&CarryList, AMULET);
corp;
/*
* carryScan - scanner routine for carry list display.
*/
proc carryScan(bool first)*char:
Id_t id;
if first then
CarryNext := CarryList;
fi;
if CarryNext = nil then
nil
else
id := CarryNext*.il_this;
CarryNext := CarryNext*.il_next;
psGet(id)
fi
corp;
/*
* statInit - initialize and set up our status indicators.
*/
proc statInit()void:
PlayerLine := 0;
PlayerColumn := 0;
MoveCount := 0;
Condition := "Healthy";
scNumber(1, "Line", 1, 1, 4, &PlayerLine);
scNumber(2, "Column", 1, 13, 4, &PlayerColumn);
scNumber(3, "Moves", 2, 1, 3, &MoveCount);
scString(4, "Condition", 2, 13, 10, &Condition);
scMult(5, "Carrying", 3, 1, 3, carryScan);
corp;
/*
* kindName - turn a word type code into a string for _psDump.
*/
proc kindName(Id_t kind)*char:
case kind
incase VERB:
"VERB"
incase ARTICLE:
"ARTICLE"
incase ADJECTIVE:
"ADJECTIVE"
incase NOUN:
"NOUN"
incase PREPOSITION:
"PREPOSITION"
incase PUNCTUATION:
"PUNCTUATION"
incase AUXILLIARY:
"AUXILLIARY"
default:
"???"
esac
corp;
/*
* verbOnly - process a verb only input command.
*/
proc verbOnly()void:
extern
_psDump(channel output text chout;
proc(Id_t kind)*char kindName)void;
ulong id;
id := pspWord(1);
case id
incase NORTH:
move(-1, 0);
scUpdate(1);
incase SOUTH:
move(+1, 0);
scUpdate(1);
incase EAST:
move(0, +1);
scUpdate(2);
incase WEST:
move(0, -1);
scUpdate(2);
incase QUIT:
Quit := true;
incase LONG:
write(TextOut;
"This is a very long set of output that the program is told to output when "
"you type in the word 'long'. This output doesn't have a whole lot of "
"significance or intelligence or meaning or whatever, but what the heck, "
"I just wanted to get something that would make more than one line of "
"output go through the TextOut channel to the screen's text area."
);
incase DUMP:
_psDump(TextOut, kindName);
default:
write(TextOut; "You must give an object with verb \"",
psGet(id), "\".");
esac;
corp;
/*
* drop - drop something.
*/
proc drop(uint pos)void:
Id_t id;
id := pspWord(pos);
if lIn(CarryList, id) then
/* player is carrying it, so delete it from the carrying list: */
lDelete(&CarryList, id);
/* request that the list on the screen be updated: */
scUpdate(5);
/* now we add it to the contents list for this location: */
lAppend(addContents(PlayerLine, PlayerColumn), id);
/* now we display the object on the map, but re-move the player on
top of it so that it is hidden "underneath" the 'me': */
scNew(id, PlayerLine, PlayerColumn, getObjectC2(id));
scMove(0, PlayerLine, PlayerColumn);
write(TextOut; "Dropped.");
else
write(TextOut; "You aren't carrying any ", psGet(id), '.');
fi;
corp;
/*
* get - get something.
*/
proc get(uint pos)void:
*ContentsList_t cl;
Id_t id;
id := pspWord(pos);
cl := findCList(PlayerLine, PlayerColumn);
if lIn(cl*.cl_contents, id) then
/* the object is here; delete it from that contents, add it to our
carrying list, and request an update of the list on screen: */
lDelete(&cl*.cl_contents, id);
lAppend(&CarryList, id);
scUpdate(5);
scDelete(id);
/* note: we leave the contents list hanging around, but it may get
used again, and anyway, we'll kill it on termination. */
write(TextOut; "Taken.");
else
write(TextOut; "There is no ", psGet(id), " here.");
fi;
corp;
/*
* process - process user's commands.
*/
proc process()void:
[79] char buffer;
*char p;
Quit := false;
while not Quit do
scRead(&buffer[0]);
p := &buffer[0];
while p* = ' ' or p* = '\t' do
p := p + 1;
od;
if p* ~= '\e' then
case psParse(&buffer[0])
incase PS_ERROR:
write(TextOut; "I don't know the word \"", pspBad(), "\".");
incase PS_NONE:
write(TextOut; "I don't understand that sentence.");
incase 1:
if not lookAround() then
write(TextOut; "There is nothing here.");
fi;
incase 2:
incase 4:
drop(3);
incase 3:
drop(4);
incase 5:
incase 7:
get(3);
incase 6:
get(4);
incase 8:
verbOnly();
default:
write(TextOut; "Can't possibly get this!");
esac;
fi;
od;
corp;
/*
* main - main program - the action starts here.
*/
proc main()void:
*byte dummy;
/* set up the various library routine sets: */
scInit();
psInit(false);
lInit();
/* open a text output channel through the screen output routine: */
open(TextOut, scPut);
/* pass a scenery generator and empty object list for map: */
dummy := scNewMap(scenery, nil);
/* define the initial viewing window for the map area: */
scWindow(0, 0);
/* define the input prompt: */
scPrompt("> ");
/* go build our dictionary and grammar: */
gramInit();
/* go set up our carrying list: */
carryInit();
/* go initialize and set up our status indicators: */
statInit();
/* set up the 'objects' in the viewing area: */
scNew(0, 0, 0, C2('m', 'e')); /* this is 'us', the key character */
scNew(1, -2, -2, C2('T', '1'));
scNew(2, -3, -8, C2('T', '2'));
scNew(3, -1, +3, C2('T', '3'));
scNew(4, +3, +2, C2('G', '1'));
scNew(5, +1, -2, C2('G', '2'));
/* say hello: */
write(TextOut;
" Welcome to the test scenario. Not much will happen here, but there "
"should be enough for you to get an idea of the kinds of things that can go "
"on. So anyway, here goes:"
);
/* go process user's commands: */
process();
/* all done, go clean up everything: */
termContents();
lFree(CarryList);
lTerm();
psTerm();
scTerm();
corp;